#ifndef AER_QUERY_HPP_
#define AER_QUERY_HPP_

#include "aerDeviceResource.hpp"


namespace aer {
  
class Query : public DeviceResource
{
  public:
    enum Target
    {      
      SAMPLES_PASSED      =  GL_SAMPLES_PASSED, 
      ANY_SAMPLES_PASSED  =  GL_ANY_SAMPLES_PASSED, 
      TIME_ELAPSED        =  GL_TIME_ELAPSED
    };
  
  
  private:
    Target m_target;
    
  
  public:
    Query() : DeviceResource() {}
    
    void generate()
    {
      AER_ASSERT( !isGenerated() );
      glGenQueries( 1, &m_id);
    }
    
    void release()
    {
      if (isGenerated()) 
      {
        glDeleteQueries( 1, &m_id);
        m_id = 0u;
      }
    }
    
    void begin(Target target)
    {
      AER_ASSERT( isGenerated() );
      m_target = target;
      glBeginQuery( m_target, m_id);
    }
    
    void end()
    {
      glEndQuery( m_target );
    }
    

  
    bool isResultAvailable()
    {
      GLint isAvailable;
      glGetQueryObjectiv( m_id, GL_QUERY_RESULT_AVAILABLE, &isAvailable);
      return GL_TRUE == isAvailable;
    }

    void getResult(GLint &result)
    {
      glGetQueryObjectiv( m_id, GL_QUERY_RESULT, &result);
    }

    void getResult(GLuint &result)
    {
      glGetQueryObjectuiv( m_id, GL_QUERY_RESULT, &result);
    }

    GLint getResulti()
    {
      GLint result = 0;
      glGetQueryObjectiv( m_id, GL_QUERY_RESULT, &result);
      return result;
    }

    GLuint getResultui()
    {
      GLuint result;
      glGetQueryObjectuiv( m_id, GL_QUERY_RESULT, &result);
      return result;
    }

  private:
    DISALLOW_COPY_AND_ASSIGN(Query);
};

}

#endif // AER_QUERY_HPP_
